﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using WebApplication1.Models.Database;

namespace WebApplication1.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class CacheController : Controller
    {
        // 注入数据库上下文
        private readonly WebEnterpriseIIContext _db;
        private readonly IMemoryCache cache;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="cache"></param>
        public CacheController(IMemoryCache cache, WebEnterpriseIIContext db)
        {
            this.cache = cache;
            _db = db;
        }

        /// <summary>
        /// 判断缓存是否存在
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> TryGetValueCache()
        {
            if (cache.TryGetValue("UserName", out _))
            {
                return "该缓存存在";
            }
            else
            {
                return "该缓存不存在";
            }
        }

        /// <summary>
        /// 读写缓存
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> GetCache()
        {
            // 写入缓存
            cache.Set("UserName", "admin");
            cache.Set("Password", "12345");

            // 读取缓存
            string userName = cache.Get<string>("UserName");
            string password = cache.Get<string>("Password");

            // 返回
            return userName + "\n" + password;
        }

        /// <summary>
        /// 读写缓存
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> GetOrCreateCache()
        {
            string userName = cache.GetOrCreate("UserName", entry =>
            {
                return "admin";
            });
            string password = cache.GetOrCreate("Password", entry =>
            {
                return "12345";
            });
            return userName + "\n" + password;
        }

        /// <summary>
        /// 删除缓存
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> RemoveCache()
        {
            // 写入缓存
            cache.Set("UserName", "admin");
            cache.Set("Password", "12345");

            // 删除缓存
            cache.Remove("UserName");
            cache.Remove("Password");

            // 返回
            return "缓存删除成功";
        }

        /// <summary>
        /// 永不过期
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> CacheTime1()
        {
            string msg = string.Empty;
            cache.Set("UserName", "admin");

            // 读取缓存
            for (int i = 1; i <= 5; i++)
            {
                msg += $"第{i}秒缓存值：{cache.Get<string>("UserName")}\n";
                Thread.Sleep(1000);
            }

            // 返回
            return msg;
        }

        /// <summary>
        /// 绝对时间过期
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> CacheTime2()
        {
            string msg = string.Empty;
            cache.Set("UserName", "admin", TimeSpan.FromSeconds(3));

            // 读取缓存
            for (int i = 1; i <= 5; i++)
            {
                msg += $"第{i}秒缓存值：{cache.Get<string>("UserName")}\n";
                Thread.Sleep(1000);
            }

            // 返回
            return msg;
        }

        /// <summary>
        /// 滑动时间过期
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> CacheTime3()
        {
            string msg = string.Empty;
            cache.Set("UserName", "admin", new MemoryCacheEntryOptions
            {
                SlidingExpiration = TimeSpan.FromSeconds(3)
            });

            // 读取缓存
            for (int i = 1; i <= 5; i++)
            {
                msg += $"第{i}秒缓存值：{cache.Get<string>("UserName")}\n";
                Thread.Sleep(1000);
            }

            // 返回
            return msg;
        }

        /// <summary>
        /// 绝对时间过期+滑动时间过期
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> Get()
        {
            string msg = string.Empty;
            cache.Set("UserName", "admin", new MemoryCacheEntryOptions
            {
                SlidingExpiration = TimeSpan.FromSeconds(1.5),
                AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(3)
            });

            // 读取缓存
            for (int i = 1; i <= 5; i++)
            {
                msg += $"第{i}秒缓存值：{cache.Get<string>("UserName")}\n";
                Thread.Sleep(1000);
            }

            // 返回
            return msg;
        }

        [HttpGet]
        public List<Good> GetGoodList()
        {
            //判断缓存有没有商品数据缓存 有的话 直接用 没有的话创建缓存
            if(cache.TryGetValue("goodCache",out List<Good> goods))
            {
                //直接用缓存
                return goods;
            }
            else
            {
                //使用本地缓存保存查询结果，缓存时间为30分钟
                //return _db.Goods.Where(x => x.Id > 0).ToList();
                //cache.Set("goodCache",good,TimeSpan.FromMinutes(30));
                //return good;
                return cache.Set("goodCache", _db.Goods.Where(x => x.Id > 0).ToList(), TimeSpan.FromMinutes(30));
            }
        }

        //商品详情接口
        [HttpGet]
        public Good GetGoodInfo(int goodId)
        {
            //获取商品详情
            var good = _db.Goods.FirstOrDefault(x => x.Id == goodId);

            //使用本地缓存保存登录用户浏览商品记录(浏览过的多个商品List)

            var userId = Response.HttpContext.User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier).Value;

            //先把之前存下来的浏览器取出来 让每一个用户的缓存key都不一样 userId不一样 让key带上userId
            var oldRecord = cache.Get<List<Good>>($"UserViews{userId}");

            List<Good> views = new List<Good>();
            views.Add(good);
            //如果旧的浏览记录不为空 就添加到列表
            if (oldRecord != null)
                views.AddRange(oldRecord);

            //把列表设置到缓存
            cache.Set($"UserViews{userId}", views);
            return good;
        }

       
    }
}
